package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.RespClaTimeRule;
import com.ruoyi.system.domain.ScClaTime;
import com.ruoyi.system.domain.ScCourseCla;
import com.ruoyi.system.domain.enums.ClaTimeRepeatTypeEnums;
import com.ruoyi.system.domain.vo.DateUtil;
import com.ruoyi.system.mapper.ScClaTimeMapper;
import com.ruoyi.system.mapper.ScCourseClaMapper;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.ScClaTimeRuleMapper;
import com.ruoyi.system.domain.ScClaTimeRule;
import com.ruoyi.system.service.IScClaTimeRuleService;

/**
 * 上课时间配置规则Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-01-05
 */
@Service
public class ScClaTimeRuleServiceImpl implements IScClaTimeRuleService 
{
    @Autowired
    private ScClaTimeRuleMapper scClaTimeRuleMapper;

    @Autowired
    private ScCourseClaMapper scCourseClaMapper;
    @Autowired
    private ScClaTimeMapper scClaTimeMapper;

    /**
     * 查询上课时间配置规则
     * 
     * @param ruleId 上课时间配置规则主键
     * @return 上课时间配置规则
     */
    @Override
    public ScClaTimeRule selectScClaTimeRuleByRuleId(Long ruleId)
    {
        return scClaTimeRuleMapper.selectScClaTimeRuleByRuleId(ruleId);
    }

    /**
     * 查询上课时间配置规则列表
     * 
     * @param scClaTimeRule 上课时间配置规则
     * @return 上课时间配置规则
     */
    @Override
    public List<ScClaTimeRule> selectScClaTimeRuleList(ScClaTimeRule scClaTimeRule)
    {
        return scClaTimeRuleMapper.selectScClaTimeRuleList(scClaTimeRule);
    }

    /**
     * 新增上课时间配置规则
     * 
     * @param scClaTimeRule 上课时间配置规则
     * @return 结果
     */
    @Override
    public int insertScClaTimeRule(ScClaTimeRule scClaTimeRule)
    {

        scClaTimeRule.setCreateUser(SecurityUtils.getUsername());
        scClaTimeRule.setCreateTime(DateUtils.getNowDate());
        int count=scClaTimeRuleMapper.insertScClaTimeRule(scClaTimeRule);
        saveBatchClaTime(scClaTimeRule);
        return count;
    }

    /**
     * 修改上课时间配置规则
     * 
     * @param scClaTimeRule 上课时间配置规则
     * @return 结果
     */
    @Override
    public int updateScClaTimeRule(ScClaTimeRule scClaTimeRule)
    {
        scClaTimeRule.setLastUpdateUser(SecurityUtils.getUsername());
        scClaTimeRule.setLastUpdateTime(DateUtils.getNowDate());
        int count=scClaTimeRuleMapper.updateScClaTimeRule(scClaTimeRule);
        scClaTimeMapper.deleteScClaTimeByCourseRuleId(scClaTimeRule.getRuleId());
        saveBatchClaTime(scClaTimeRule);

        return count;
    }

    /**
     * 批量删除上课时间配置规则
     * 
     * @param ruleIds 需要删除的上课时间配置规则主键
     * @return 结果
     */
    @Override
    public int deleteScClaTimeRuleByRuleIds(Long[] ruleIds)
    {scClaTimeMapper.deleteScClaTimeByRuleIds(ruleIds);
        return scClaTimeRuleMapper.deleteScClaTimeRuleByRuleIds(ruleIds);
    }

    /**
     * 删除上课时间配置规则信息
     * 
     * @param ruleId 上课时间配置规则主键
     * @return 结果
     */
    @Override
    public int deleteScClaTimeRuleByRuleId(Long ruleId)
    {

        scClaTimeMapper.deleteScClaTimeByCourseRuleId(ruleId);
        return scClaTimeRuleMapper.deleteScClaTimeRuleByRuleId(ruleId);
    }

    /**
     * 保存 具体上课日期
     *
     * @param claTimeRule
     */
    private void saveBatchClaTime(ScClaTimeRule claTimeRule) {
        Long claId = claTimeRule.getClaId();
        ScCourseCla courseCla = scCourseClaMapper.selectScCourseClaByClaId(claId);
        BigDecimal everyStuLoseHour = courseCla.getEveryStuLoseHour();

        List<RespClaTimeRule> claTimeList = getClaTimeListByRule(claTimeRule, null);

        List<ScClaTime> timeList = claTimeList.stream().map(item -> {
            ScClaTime claTime = new ScClaTime();
            claTime.setRuleId(claTimeRule.getRuleId());
            claTime.setClaId(claTimeRule.getClaId());
            claTime.setClaDate(item.getClaDate());
            claTime.setStartTime(item.getClaTimeBegin());
            claTime.setEndTime(item.getClaTimeEnd());
            claTime.setPayTotalHour(everyStuLoseHour);

            claTime.setAtClassCnt(Math.toIntExact(courseCla.getCapacity()));
//            // 排课
//            claTime.setSource("1");
//            // 待上课
//            claTime.setStatus("1");
            claTime.setRoomId(claTimeRule.getRoomId());
            claTime.setRoomName(claTimeRule.getRoomName());
            claTime.setCourse(claTimeRule.getCourse());
            claTime.setTeacherId(claTimeRule.getTeacherId());
            claTime.setCreateUser(claTimeRule.getCreateUser());
            return claTime;
        }).collect(Collectors.toList());
        for (ScClaTime scClaTime:timeList
             ) {
            scClaTimeMapper.insertScClaTime(scClaTime);
        }
    }


    public List<RespClaTimeRule> getClaTimeListByRule(ScClaTimeRule claTimeRule, Map<String, String> holidayMap) {
        RespClaTimeRule respClaTime = RespClaTimeRule.builder()
                .claTimeBegin(claTimeRule.getStartTime())
                .claTimeEnd(claTimeRule.getEndTime())
                .build();

        BeanUtils.copyProperties(claTimeRule, respClaTime);

        return this.getClaTimeListByRule(respClaTime, holidayMap);
    }


    public List<RespClaTimeRule> getClaTimeListByRule(RespClaTimeRule itemTime, Map<String, String> holidayMap) {
        List<RespClaTimeRule> resultClaTimeList = Lists.newArrayList();




//        String ruleType = itemTime.getRuleType();
//        String repeatType = itemTime.getRepeatType();
        String weekDay = itemTime.getWeekDay();
//        boolean filterHoliday = itemTime.isFilterHoliday();
        DateTime beginDate = DateUtil.yyyMMddDayBegin(itemTime.getBeginDate());
        DateTime endDate = DateUtil.yyyMMddDayEnd(itemTime.getEndDate());



        // 周几上课
        List<String> weekDayList = Arrays.asList(weekDay.split(","));



        // 非单次排课 计算所有上课日期
        DateTime cycleBeginDate = beginDate;
        DateTime cycleEndDate = endDate;

            while (cycleBeginDate.isBefore(cycleEndDate)) {

                // 每周重复
                int dayOfWeek = cycleBeginDate.getDayOfWeek();
                boolean contains = weekDayList.contains(String.valueOf(dayOfWeek));

                if (!contains) {
                    // 不上课
                    cycleBeginDate = cycleBeginDate.plusDays(1);
                    continue;
                }



                RespClaTimeRule respClaTime = RespClaTimeRule.builder()
                        .claName(itemTime.getClaName())
                        .courseName(itemTime.getCourseName())
                        .staffName(itemTime.getStaffName())
                        .claDate(cycleBeginDate.toString("yyyy-MM-dd"))
                        .claTimeBegin(itemTime.getClaTimeBegin())
                        .claTimeEnd(itemTime.getClaTimeEnd())
                        .build();
                respClaTime.setRuleId(itemTime.getRuleId());
                respClaTime.setCourseName(itemTime.getCourseName());

                resultClaTimeList.add(respClaTime);

                cycleBeginDate = cycleBeginDate.plusDays(1);
            }
        return resultClaTimeList;
    }
}
